#pragma once
#include "..\DXAMLCommon.h"
#include "Base.h"
#include "StringPtr.h"


typedef bool (*PFNCOMP)(StringPtr *pstrA, StringPtr *pstrB);
typedef XUINT32 (*PFNHASH)(StringPtr *pstr, XUINT32 hashSeed);


//&IsStringPtrEqual,&ComputeStringPtrHash
template<typename TKEY,typename TV,PFNCOMP COMP,PFNHASH HASH>
class Dictionary :
	public Base
{

private: 
	static const unsigned long c_centryMinCapacity;

public: 
	Dictionary(struct IMalloc *);
	virtual ~Dictionary();
	HRESULT Initialize(unsigned long);
	HRESULT Clear();
	bool Lookup(const struct StringPtr * key, XUINT32 * pvalue) const;
	HRESULT Insert(const struct StringPtr * key, XUINT32 value, XUINT32 * pvaluePrevious);
	HRESULT Remove(const struct StringPtr *);
	unsigned long GetCount();
	void StartIteration();
	bool MoveToNextItem(XUINT32 *);

	template<TTTKEY,TTTV>
	struct SEntry<TTTKEY,TTTKEY>
	{
	public: 
		TTTKEY m_key;
		unsigned long m_hashKey;
		TTTV m_value;
		bool IsEmpty();
		bool IsDeleted();
		bool IsUsed();
	};
private: 
	struct SEntry<TKEY,TV> * m_pentryTable;

	unsigned long m_centryTable;
	unsigned long m_centry;
	unsigned long m_centryNonEmpty;
	unsigned long m_hashSeed;
	unsigned long m_ientryIterator;
	unsigned long ComputeKeyHashInternal(TKEY);
	bool FindEntry(TKEY key, unsigned long hashKey, unsigned long * pientry, unsigned long * pientryFirstDeleted) const;
	HRESULT Grow();
};